home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-23 | 17.3 KB | 567 lines | [TEXT/ALFA] |
-
- CGI shell, version 1.3.2
-
- (This document replaces the old documentation for versions 1.1, 1.2, 1.3,1.3.1)
-
- This documentation, the software it describes, and the source code included
- with this package is:
-
- Copyright, Ronald T. Kneusel, 1995, 1996. All Rights Reserved.
- rkneusel@post.its.mcw.edu
-
- Distribution permitted if the entire archive is intact. If you want to
- put this on CD-ROMs then you need to contact me first.
-
- ---------------------------------------------------------------------------------
-
- WHAT'S NEW
-
-
- 1.3.2 (23-Apr-96): Rewrote @Field to make it more stable.
-
- 1.3.1 (17-Apr-96): Added #digits variable to control number of decimal places
- when !val stores a floating point number. Default 6.
-
-
- ---------------------------------------------------------------------------------
-
-
- *****************************
- * *
- * INTRODUCTION *
- * *
- *****************************
-
-
- DISCLAIMER
-
-
- This is a tool for programmers; Forth programmers in particular. Therefore,
- this documentation is intentionally sparse. After all, real programmers don't
- need no steenkin' documentation, right? :)
-
-
-
- WHAT IS IT?
-
- CGI shell works with Chris Heilman's Pocket Forth programming language to
- provide a skeleton for creating custom CGI applications for WebSTAR/MacHTTP.
- The shell code handles AppleEvents, the interpretation of forms data, and
- supplies a set of words for building a reply string. Pocket Forth, version 6.5
- is included in the release.
-
-
-
- WHAT DO I NEED TO RUN IT?
-
- • A Mac running WebSTAR (commercial) or MacHTTP (shareware)
- • This code
- • A text editor (Teachtext or Simpletext will do in a pinch)
- • Some Forth and HTML programming experience
-
-
-
- ABOUT THE SHELL SOURCE CODE
-
- There are two layers to the shell code. The file SERVER.4TH contains
- a minimal web server interface. Only the simplest of CGI applications will
- use this file alone. The second, more powerful, layer is contained in the
- files: STRING.4TH, FIELD.4TH, and TEMPLATE.4TH. Unless the CGI you wish to
- create is exceedingly simple it is best to use the SHELL.4TH file as it contains
- all the files above in the proper order.
-
- The remainder of this file is split into two parts: SERVER.4TH and SHELL.4TH
- which describe the low-level and high-level interface code respectively.
-
-
-
- CONTENTS
-
-
- • Part 1 -- Low level routines
-
- • Part 2 -- High level routines
-
-
- ================================================================================
-
-
- *************************************
- * *
- * Part 1 SERVER.4TH - low level *
- * *
- *************************************
-
-
-
- A FIRST EXAMPLE
-
-
- A minimal CGI using the SERVER.4TH file alone is:
-
-
- \ Simple CGI
-
- --> server.4th ( load only the minimal CGI code )
-
- message[ s1 You are: ] ( strings used in the reply )
- message[ s2 <br>Using: ]
- message[ s3 <br>And your favorite flavor is: ]
-
- message[ fname flavor] ( name of the field )
-
- 512 String>> out ( return string goes here, 512 char max )
- out newstr ( clear it )
-
- ,s sdoc ,s WWWΩ ae: ( begin the AppleEvent reply handler )
-
- out startstring ( add HTML header )
-
- s1 out strcpy ( add 'You are: ' )
- out APPEND @Addr ( add client's IP address )
-
- s2 out strcpy ( add '<br>Using: ' )
- out APPEND @Browser ( add browser type )
-
- s3 out strcpy ( add '<br>And your favorite flavor is: ' )
- out fname APPEND @Field ( add flavor field data )
-
- out endstring ( add HTML ending )
-
- out REPLY bye ( send the reply and quit )
-
- ;ae ( end reply handler )
-
-
-
- This CGI will respond to an HTML form like this one:
-
-
- <h1> Simple CGI test </h1>
- <form method=post action="simple.cgi">
- What is your favorite ice cream flavor?
- <select name="flavor"
- <option>Vanilla <option>Chocolate <option>Strawberry
- </select>
- <input type=submit value="Send it">
- </form>
-
-
- To create 'simple.cgi' load the Forth code above into a *copy* of Pocket Forth
- and then enter save bye to save the dictionary. Use a web browser to bring
- up the HTML file, call it 'simple.html', and click 'send it'. If all went well
- you will receive a reply indicating who you are, what you are using, and
- (presumably) your favorite type of ice cream.
-
-
-
- MAIN USER LEVEL WORDS
-
-
- The most important words defined by SERVER.4TH are @Direct, @Addr, @Browser,
- and @Field. These words fetch information sent by the web server to the CGI
- application.
-
-
- @Direct (e.g. out APPEND @Direct )
-
- Direct returns the direct argument attached to the action component of the
- form definition. If the HTML file contains:
-
- <form method=post action="my.cgi$3.141592">
-
- Then the phrase out APPEND @Direct will append the string 3.141592 to
- the string contained in out . If NEW is specified in place of APPEND
- the direct argument replaces the previous contents of the string. All
- strings are terminated with a '\0' character.
-
-
- @Addr (e.g. out APPEND @Addr )
-
- Addr returns the IP address string of the client. If the address has a
- DNS entry its name will be returned. If there was no DNS entry the reversed
- in-arpa numerical IP address is returned. NEW and APPEND work as above.
-
-
- @Browser (e.g. out NEW @Browser )
-
- Browser returns a string indicating what type of web browser the client
- is using. This can be useful for deciding when to return a graphically
- intensive page and when not to. @Browser works as @Addr and @Direct.
-
-
- @Field (e.g. out f1 APPEND @Field )
-
- Field places the contents of the field whose name is in the string f1
- into the string out . NEW and APPEND work as before. @Field will handle
- all translation of characters.
-
-
- REPLY (e.g. out REPLY )
-
- REPLY returns the string on the stack to the web server which then sends
- it down to the client. This word must be called only from within a
- ae: ... ;ae pair.
-
-
- SETTING UP THE APPLE EVENT HANDLER
-
- The heart of a CGI application is the AppleEvent handler that responds to the
- AppleEvent sent by the web server. In Pocket Forth an AppleEvent handler is
- first defined and then saved to the dictionary. When the application is then
- launched the handler is added to the list of handlers and the application
- will respond to the event whenever it is listening for events. Pocket Forth
- listens to system events when waiting for input so it is unnecessary to
- be concerned about handling local events (i.e. mouse clicks, keypresses, etc.)
- In fact, Pocket Forth can be used normally while still listening for
- AppleEvents. If you write the CGI to quit when finished you do not need to
- write any code for dealing with the server Mac. This is unlike the C based
- Responder CGI shell.
-
- In Pocket Forth an Apple Event handler is defined using ae: and ;ae,
-
- ,s sdoc ,s WWWΩ ae: \ begin the handler for the sdoc,WWWΩ event
-
- ...some code here...
-
- ;ae
-
- The general process, then, is:
-
- ,s sdoc ,s WWWΩ ae:
-
- <get data from the apple event using @Direct, @Field, etc.>
-
- <manipulate the data and create an output string>
-
- <reply to the event with <output-string> REPLY>
-
- <quit or re-initialize the application>
-
- ;ae
-
- See the included examples for more information.
-
-
- STRING SUPPORT WORDS
-
- The CGI shell provides a number of words for manipulating null terminated
- strings. These are summarized below:
-
-
- message[ ( compile: <name> <text>] )
- ( run: -- address )
-
- Create <name>, a null terminated string. E.g.
- message[ s0 <h1>Result...</h1>]
-
- String>> ( size -- (<name>) )
-
- Create a string, <name>, <size> bytes long. E.g.
- 512 String>> theReply
-
- strcpy ( s1 s2 -- )
-
- Append s1 to s2. Appending is useful for creating reply
- strings, use strncpy to avoid appending.
-
- length ( s -- n )
-
- Return the length of string s.
-
- newstr ( s -- )
-
- Zero the string s. Equal to 0 s c!
-
- 0type ( s -- )
-
- Type the null terminated string s on the screen. Useful for
- debugging.
-
- accept ( s length -- )
-
- Identical to expect but adds a terminating '\0'.
-
- startstring ( s -- )
-
- Add <HTML> to the string s.
-
- endstring ( s -- )
-
- Append </HTML> to the string s.
-
-
- NUMERICAL CONVERSION
-
- Pocket Forth has complete support for floating point numbers making it useful
- for scientific applications. These words will convert between floating point
- numbers and strings.
-
-
- f>str ( f s -- )
-
- Put the floating point number f into the string using the current
- settings for FIX or SCI.
-
- str>f ( s -- f )
-
- Make s into a floating point number on the stack.
-
-
-
-
- *************************************
- * *
- * Part 2 SHELL.4TH - high level *
- * *
- *************************************
-
-
- This is where the real power lies. The code in SHELL.4TH allows you to create
- an external file with all the HTML to be returned and to place markers in the
- file to indicate where to substitute values (strings or numbers). This
- separates the HTML source from the program itself and allows you to alter the
- appearance without recompiling the application. It also save valuable
- dictionary space by not including a lot of text.
-
- Say we have a web page that looks like this:
-
- <form method=post action="ftest.cgi">
- Name? <input type="text" name="name"><p>
- Age? <input type="text" name="age"><p>
- Weight? <input type="text" name="weight">
- <p><input type=submit value="Go">
- </form>
-
- This creates a form that asks for three values:
-
- - a name (a string)
- - an age (an integer)
- - a weight (floating point)
-
- It then calls a CGI application named 'ftest.cgi' which looks like this:
-
-
- \ simple CGI
-
- --> shell.4th \ load CGI shell code
-
- $[ file ftest.txt] \ name of HTML code file
-
- 2048 String>> out \ reply goes in here
-
- STR 80 " name" #field f1 \ define the name field
- INT 15 " age" #field f2 \ and the age field
- FP 20 " weight" #field f3 \ and the weight field
- STR 80 " a_string" #object s1 \ plus an extra string (no reason)
-
- message[ ss Get a life, Bozo!] \ a constant string
-
- ,s sdoc ,s WWWΩ ae: \ start the AppleEvent reply
- <getFields> \ automatically load field data
- ss s1 !val \ put the text in the s1 object
- out file NEW template \ call template to fill in reply
- out REPLY \ send the reply
- bye \ and quit
- ;ae
-
-
- Which uses the template word to read the file 'ftest.txt':
-
-
- <body bgcolor="#ffffff">
- <font color="#ff0000">
- <h1>The Big Cheese</h1>
- <hr><font size=+2 color="#339944">
- You are: <b>`name`</b> <p>
- You are <b>`age`</b> years old. <p>
- You weigh <b>`weight`</b> pounds.
- </font>
- <h2>`a_string`</h2>
-
-
- Notice the values in ` (backquotes)? These are the names of the fields
- and objects which will have their values substituted in the reply.
-
-
-
- WHAT'S THIS 'FIELD' AND 'OBJECT' BUSINESS?
-
-
- There is only one difference between a FIELD and an OBJECT: fields are
- automatically entered in the field array upon their definition. This
- array is used by <getFields> to load the field data from the Apple Event.
- Almost all of your CGIs will start with a call to <getFields>.
-
- There is a second array, called the template array, which holds pointers to
- all the items that are within the backquotes in the template file.
- Fields are entered in this array, as are objects, when they are defined.
-
- Three types of Objects/Fields exist: string, integer, and float. The
- general memory structure for an object is:
-
-
- +----+--------+-----------+---------------+
- |type| name | value ... | text ........ |
- +----+--------+-----------+---------------+
-
-
- where:
-
- type (1 byte) = 0 STR, 1 INT, 5 FP
- name (30 bytes) = null terminated text of field name
- value (0,2,10 bytes) = value of field, for STR is same as start of text,
- 2 bytes for INT, 10 bytes for FP
- text (varies) = text string of value, i.e. INT is 2 then text is "2"
-
-
- When the fields are loaded from the Apple Event they are automatically
- filled in according to their type. Values stored in the field are also
- automatically stored as the proper type (for Forth) and as a text string
- (for the web server).
-
- The template handles looking up names in the template file and
- substituting the right text, you do not need to be at all concerned about
- it. This is a big improvement over the array fiddling necessary in the
- previous version.
-
-
-
- USING OBJECTS/FIELDS
-
-
- Part of the goal in this new version is to make transparant the necessary
- switching between numerical values and strings. The other major goal was
- to remove the array fiddling and let the programmer have easy access to
- the template file.
-
- Let's define a field:
-
- FP 20 " spin" #field sp ( spin quantum number )
-
- We have created a field named 'spin' that acts like a variable, i.e.
- referencing sp returns the address of the beginning of the field. So,
- what is it:
-
- FP -- floating point field
- 20 -- string part is 20 characters long (no bounds checks!)
- " spin" -- the name part is 'spin'
- sp -- the dictionary name (Forth) for this object
-
- The parts of the record are accessed via:
-
- sp .type -- push field type on the stack (0=STR,1=INT,5=FP)
-
- sp .name -- push address of beginning of name field on stack
-
- sp .val -- address of value part
-
- sp .text -- address of the text part
-
-
- Values are read from and written to the field from within the program by:
-
- @val -- return the current value of the field:
- -- address of text part if it is a string
- -- 16-bit integer if of type INT
- -- floating point number if of type FP
-
- !val -- store in the current record, if string then copy, if a
- number then store in value part and then store a string
- of the number in the text part.
-
-
- ** Note: The number of decimal places !val uses when storing a floating
- point number is determined by the value of the variable #digits
- The default is 6, 3 #digits ! would set it to three.
-
-
- Example, using the field above:
-
- 1.5 sp !val
- ( put 1.5 in the value part and "1.5" in the string part)
-
- sp @val 2.0 f* f.
- ( get the value part, 1.5, and multiply by 2, prints 3.0)
-
-
- This transparent conversion between string and number when coupled with
- the automatic initialization and substitution of values is what makes the
- full CGI shell useful.
-
-
-
- TEMPLATES
-
-
- The word TEMPLATE accepts an output string and a file name. It then
- reads the file into the output string substituting the text part of
- FIELDs and OBJECTs whose names are delimited within the file by `
- (backquotes).
-
- Unlike the previous version of the CGI shell, there is nothing else for
- the programmer to do. TEMPLATE does all the searching for matches between
- the name read from the file and the names of fields and objects that were
- stored when defined.
-
- Specifically:
-
-
- template ( output-string-address filename-addr NEW|APPEND )
- -1 0
-
- NEW and APPEND are constants defined in SERVER.4TH. If NEW the output
- string is cleared before use, if APPEND the template file is appened to
- the end of the existing string.
-
- The filename string *MUST* be defined with the word $[ as it needs to be
- a counted string and not a null terminated string:
-
- $[ f1 ftest.txt] \ ] ends the text, no spaces
- 2048 String>> out \ a 2k output buffer
-
- out f1 NEW template \ fill the string with the text in ftest.txt
-
-
- It's that easy! Look at the included sample code to learn more.
-
-
- =================================================================================
-
-
- NOTES
-
- The best way to learn to use the shell is to experiment. See the 'Deflect'
- example to learn how to force the client's browser to another URL. When
- developing a CGI keep the following in mind:
-
-
- * turn off the processor cache if using an '040 based Mac. Some code will
- compile with it on but often the application quits part way through. The
- compiled code runs just fine with the cache on.
-
-
- * always use a fresh copy of the Pocket Forth application when re-compiling.
-
-
- * remember to do save bye after loading the code. Amazing how many times
- I forget to do that!
-
-
- The software carries no warranty of any kind. If it blows up and kills
- your hard drive, don't come whining to me about it. (It won't, no worries :)
- Caveat Emptor.
-
- Ron Kneusel
- 8725 West Burdick Ave.
- Milwaukee, WI 53227 USA
- (414) 545-7557
- rkneusel@post.its.mcw.edu
-
- The latest version of CGIshell can always be found at:
-
- http://kreeft.intmed.mcw.edu/pf.html
- ftp://kreeft.intmed.mcw.edu/q/pub/forth/
-
- March 1996, AMDG
-